﻿''
''Copyright Zac McKenzie 2012
''

'This class loads the tv listings for a particular Channel/ Day.
'It does this by loading each tv guide listing as a "scheduled event"

Imports st = System.Text
Imports System.DateTime
Imports System.IO
Imports System.IO.Compression
Imports sxl = System.Xml.Linq
Imports System.Linq

Public Class tvGuideListing
    Public xmlString As String
    Public xmlData() As Byte
    Dim doc As sxl.XDocument

    Public tvGuideScheduledEventsList As List(Of scheduledEvent) = New List(Of scheduledEvent)

    Public Sub New(ByVal svcDetail As svc, ByVal programDate As String)
        Dim progListing = svcDetail.channelName & "_" & programDate
        Dim fileName = "c:\tv\" & progListing & ".xml"
        If Not My.Computer.FileSystem.DirectoryExists("c:\tv") Then My.Computer.FileSystem.CreateDirectory("c:\tv")

        If My.Computer.FileSystem.FileExists(fileName) Then
            doc = Nothing
            'if this day/channel guide is younder than the threadhold, read the local copy of the guide
            If My.Computer.FileSystem.GetFileInfo(fileName).LastWriteTime.AddDays(config.refreshDays) > Now Then
                wizScheduleCheckerMain.statusBar.Text = "Getting OzTivo Guide for " & programDate & " / " & svcDetail.channelName & " from file"
                System.Windows.Forms.Application.DoEvents()
                doc = sxl.XDocument.Load(fileName)
            Else
                wizScheduleCheckerMain.statusBar.Text = "Getting OzTivo Guide for " & programDate & " / " & svcDetail.channelName & " stale local copy"
                System.Windows.Forms.Application.DoEvents()
                'if this day/channel guide is older than the threadhold, refresh the guide
                My.Computer.FileSystem.DeleteFile(fileName)
                getData(svcDetail.channelName, programDate)
            End If

        Else
            wizScheduleCheckerMain.statusBar.Text = "Getting OzTivo Guide for " & programDate & " / " & svcDetail.channelName & " no local copy"
            System.Windows.Forms.Application.DoEvents()
            getData(svcDetail.channelName, programDate)
        End If
        If Not doc Is Nothing Then parse(doc)
    End Sub
    Public Sub getData(ByVal channelName As String, ByVal programDate As String)

        'set up credentials for oz tivo access
        Dim myCred As New System.Net.NetworkCredential(config.ozTivoUserName, config.ozTivoUserPassword, Nothing)
        Dim webClient As System.Net.WebClient = New System.Net.WebClient()
        webClient.Credentials = myCred

        webClient.Headers("User-Agent") = "homeGrown/0.0.1"
        webClient.Headers("Accept-Encoding") = "gzip"

        Try
            xmlData = webClient.DownloadData("http://xml.oztivo.net/xmltv/" & channelName & "_" & programDate & ".xml.gz")
        Catch ex As Exception
            wizScheduleCheckerMain.statusBar.Text = wizScheduleCheckerMain.statusBar.Text & " Not Available"
            System.Windows.Forms.Application.DoEvents()
            'so that I won't look for this data again for 1 day I'll write a dummy entry into the file
            My.Computer.FileSystem.WriteAllText("c:\tv\" & channelName & "_" & programDate & ".xml", "<tv/>", False)
            Return
        End Try

        xmlString = st.Encoding.ASCII.GetString(xmlData)
        xmlString = st.Encoding.UTF8.GetString(xmlData)

        'turn the gzipped memory stream into normal xml
        Dim x As System.IO.MemoryStream = New MemoryStream(xmlData)
        Dim zipStream As System.IO.Compression.GZipStream = New GZipStream(x, System.IO.Compression.CompressionMode.Decompress)

        Dim tempBytes(409600) As Byte
        xmlString = ""
        Dim nextBuff As String
        Dim i As Integer = 0
        Do
            i = zipStream.Read(tempBytes, 0, tempBytes.Length)
            nextBuff = st.Encoding.ASCII.GetString(tempBytes)
            xmlString = xmlString & nextBuff
        Loop While i <> 0
        xmlString = xmlString.Substring(xmlString.IndexOf("<tv g") - 1)
        xmlString = xmlString.Substring(1, xmlString.IndexOf("</tv>") + "</tv>".Length)
        doc = sxl.XDocument.Parse(xmlString)

        doc.Save("c:\tv\" & channelName & "_" & programDate & ".xml")
        x.Dispose()
        webClient.Dispose()

    End Sub

    Public Function parse(ByVal thisDoc As sxl.XDocument) As List(Of scheduledEvent)

        For Each t As sxl.XElement In thisDoc.Descendants("title")

            Dim start_dt As DateTime = parse(t.Parent.@start)
            Dim stop_dt As DateTime = parse(t.Parent.@stop)
            Dim proglength As Integer = stop_dt.Subtract(start_dt).Hours * 60 + stop_dt.Subtract(start_dt).Minutes
            Dim duration As Integer = proglength * 60

            Dim y As IEnumerable(Of sxl.XElement) = t.Parent.Descendants("category")
            Dim c = New List(Of String)

            For Each cc As sxl.XElement In y
                Dim s = cc.Value
                c.Add(s)
            Next

            Dim c1, c2, c3, c4, c5 As String

            If c.Count > 1 Then c1 = c(0) Else c1 = ""
            If c.Count > 2 Then c2 = c(1) Else c2 = ""
            If c.Count > 3 Then c3 = c(2) Else c3 = ""
            If c.Count > 4 Then c4 = c(3) Else c4 = ""
            If c.Count > 5 Then c5 = c(4) Else c5 = ""

            Dim desc As String = t.Parent.<desc>.Value

            If stop_dt < Now Then Continue For
            Dim ts = New scheduledEvent(t.Value, start_dt, stop_dt, progLength, duration, t.Parent.@channel, "", t.Parent.<rating>.<value>.Value, t.Parent.<star-rating>.<value>.Value, c1, c2, c3, c4, c5, desc)
            tvGuideScheduledEventsList.Add(ts)
            xmlString = xmlString & vbLf & ts.ToString
        Next
        Return tvGuideScheduledEventsList
    End Function
    Public Function parse(ByVal s As String) As DateTime
        Dim year = s.Substring(0, 4)
        Dim month = s.Substring(4, 2)
        Dim day = s.Substring(6, 2)
        Dim hour = s.Substring(8, 2)
        Dim minute = s.Substring(10, 2)
        'Dim offset As Int16 = Integer.Parse(s.Substring(16, 2)) + 1
        Dim d As DateTime = DateTime.Parse(year & "/" & month & "/" & day & " " & hour & ":" & minute)
        'd = d.AddHours(offset)
        Return d
    End Function

End Class
